Skip to main content

第 2 课:TCP/UDP 协议

(七)数据传输

在上面我们介绍了 “网络寻址” 的原理,这里我们重点讲 “数据传输” 的原理。

假设现在通信的通道已经建立好了(绿色的三层),而我们现在要关心数据怎么传输。也就是上面提到的数据包中的最后一列。

image-20250907161028856

实际的 web 服务中,不同的进程需要使用 不同的的端口,因此上面的数据包中还要加上目标端口

数据链路层头部网络层头部传输层头部数据包
源 mac: LL-LL-AA源 IP:192.168.0.23源端口:114
目标 Mac:le-le-le目标 IP:192.168.1.44目标端口:514

由此我们 从主机到主机间的通信,细化到了 进程和进程之间的通信。并且部分实现了 UDP 协议,当然 UDP 协议除了端口其实还需要数据包长度和校验值。

这就引出了一个问题,如果 A -> B 的网络环境不可靠,有数据包在中途丢失该怎么处理呢?

我们的思路如下:

  • A 怎么知道 包丢了?B 告诉 A
  • 丢了的包怎么办? 重传

因此 A 每发一个包,都必须收到 来自B 的 确认包 ACK, 如果在一定时间内没有收到 ACK,就重传,这叫 停止等待协议

但是这样发一次收一次的通讯速度太慢了,因此采取了 一边发一边收 同时进行的策略。

但是又出现了新的问题,如果不同的数据包走了不同的路由,导致了接受顺序和发出顺序不同,该怎么解决呢?

image-20250907162210636

因此需要在数据包上加上序号,B 返回的 ACK 确认包上也要带上对应序号

注意,如果 B 发出了 ACK3 并且被A成功接受到了,即使 A 没有收到 ACK1、ACK2,也会认为数据包 1、2 已经被成功接受。这个机制叫 累计确认/累计应答

这就又出现了一个新问题:如果A 传输的速度过快,B接受不过来该怎么办?

因此需要在 数据包 和 ACK 包 中都加上 窗口大小,表示自己的接受能力。

假如 B 返回的 ACK 包中的窗口大小 win = 5,表示最多 5 个数据包,那么 A 会把要发送的数据包分为这 4 类。

在下图中,一个数字代表一个数据包,随着 A 不断收到新的 ACK 确认号,蓝色窗口不断向右移动,A 只能不断发送蓝色窗口内还没被发送的数据包。

image-20250907162914686

注意:B 返回给 A 的窗口大小不是固定的,因此途中蓝色窗口的大小会实时调整。

这个机制被称为:滑动窗口

滑动窗口用于 流量控制,解决的是接受能力的问题。

如果 B 的接受能力很大,但是网络环境不好,导致拥塞问题丢失了一些包,该怎么处理呢?

网路拥塞问题的解决依然依赖窗口机制,但是这个窗口大小不是由 B 告诉 A 的,而是 A 主动发包试探得到的,有很多复杂的算法。

最终A 发包的 实际窗口大小 取决于 拥塞窗口滑动窗口 的最小值。

win = min(cwnd,rwnd)

A 在给 B 发送数据包之前,需要确认 B 在监听,网络通道已经建立,这依赖于 三次握手机制

下面是流程

状态图示
准备状态image-20250907164319862
第一次握手image-20250907164340405
第二次握手image-20250907164415323
第三次握手image-20250907164457085
状态建立完成image-20250907164515659